package com.webfoot.prefuse;



import java.awt.Insets;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.geom.Rectangle2D;
import java.sql.Date;
import java.text.NumberFormat;
import java.util.GregorianCalendar;
import java.util.Locale;

import javax.jws.Oneway;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;

import prefuse.Constants;
import prefuse.Display;
import prefuse.Visualization;
import prefuse.action.ActionList;
import prefuse.action.RepaintAction;
import prefuse.action.assignment.ColorAction;
import prefuse.action.assignment.DataColorAction;
import prefuse.action.layout.AxisLabelLayout;
import prefuse.action.layout.AxisLayout;
import prefuse.action.layout.Layout;
import prefuse.data.Schema;
import prefuse.data.Table;
import prefuse.data.query.NumberRangeModel;
import prefuse.render.AxisRenderer;
import prefuse.render.DefaultRendererFactory;
import prefuse.render.LabelRenderer;
import prefuse.render.Renderer;
import prefuse.render.RendererFactory;
import prefuse.util.ColorLib;
import prefuse.util.FontLib;
import prefuse.util.PrefuseLib;
import prefuse.util.ui.UILib;
import prefuse.visual.VisualItem;
import prefuse.visual.expression.InGroupPredicate;
import prefuse.visual.expression.VisiblePredicate;
import prefuse.visual.sort.ItemSorter;
import prefuse.visual.tuple.TableDecoratorItem;

class TestLayout{

	public void start(){
		Locale.setDefault(Locale.GERMANY);
		UILib.setPlatformLookAndFeel();
		
		Table table = generateTable();
		final JComponent display = createVisualization(table);
		
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				createAndShowGUI(display);
			}
		});
	}
	
	private static final Schema DECORATOR_SCHEMA = PrefuseLib.getVisualItemSchema(); 
    static { 
    	DECORATOR_SCHEMA.setDefault(VisualItem.INTERACTIVE, false); 
    	DECORATOR_SCHEMA.setDefault(VisualItem.TEXTCOLOR, ColorLib.rgb(0, 0, 255)); 
    	DECORATOR_SCHEMA.setDefault(VisualItem.FONT, FontLib.getFont("Tahoma",11));
    }
    
	public Table generateTable(){
		Table table = new Table();
		
		table.addColumn("days", int.class);
		table.addColumn("hours", int.class);
		table.addColumn("summary", String.class);
		
		table.addRows(24*8);
		
		// initialize the whole table
		int x=0;
		for(int i = 1; i<= 8; i++){
			for(int j = 0; j<=23; j++){
				table.set(x, 0, i);
				table.set(x, 1, j);
				table.set(x,2,"");
				x++;
			}
		}
		
		table.set(1, 0, 1);
		table.set(1, 1, 5);
		
		table.set(2, 0, 4);
		table.set(2, 1, 15);
		
		table.set(3, 0, 5);
		table.set(3, 1, 20);
		
		table.set(1,2,"Kick-Off Meeting");
		table.set(2,2,"Excursion to Bratislava");
		table.set(3,2,"Birthday of Sue");
		
		return table;
	}
	
	public JComponent createVisualization(Table table){
		final Visualization vis = new Visualization();
		final Display display = new Display(vis);
		vis.add("data", table);
		
		LabelRenderer nameLabel = new LabelRenderer("summary");
		nameLabel.setRoundedCorner(8, 8);
		
		DefaultRendererFactory rf = new DefaultRendererFactory(); 
		rf.setDefaultRenderer(nameLabel);
		rf.add(new InGroupPredicate("ylab"), 
				new AxisRenderer(Constants.FAR_LEFT, Constants.CENTER));
		rf.add(new InGroupPredicate("xlab_labels"), 
				new AxisRenderer(Constants.CENTER, Constants.FAR_TOP));
		rf.add(new InGroupPredicate("xlab_axis"), 
				new AxisRenderer(Constants.CENTER, Constants.FAR_TOP));
		vis.setRendererFactory(rf);
		
		vis.addDecorators("TABEL_LABELS", "data", DECORATOR_SCHEMA);
	    
		AxisLayout xAxis = new AxisLayout("data", "days", Constants.X_AXIS, VisiblePredicate.TRUE);
		AxisLayout yAxis = new AxisLayout("data", "hours", Constants.Y_AXIS, VisiblePredicate.TRUE);
		
		xAxis.setRangeModel(new NumberRangeModel(1, 8, 1, 8));
		yAxis.setRangeModel(new NumberRangeModel(0, 23, 0, 23));
		
		final Rectangle2D boundsData = new Rectangle2D.Double();
		final Rectangle2D boundsLabelsX = new Rectangle2D.Double();
		final Rectangle2D boundsLabelsY = new Rectangle2D.Double();
		
		boundsLabelsX.setRect(60, 30, 700-2*60, 450-2*30);
		boundsLabelsY.setRect(60, 30, 700-2*60, 450-2*30);
		
		xAxis.setLayoutBounds(boundsLabelsX);
		yAxis.setLayoutBounds(boundsLabelsY);
		
		myAxisLabelLayout xLabels = new myAxisLabelLayout("xlab_labels", xAxis, boundsLabelsX);
		AxisLabelLayout xLabels2 = new AxisLabelLayout("xlab_axis", xAxis, boundsLabelsX);
		AxisLabelLayout yLabels = new AxisLabelLayout("ylab", yAxis, boundsLabelsY);
		
		NumberFormat nf = NumberFormat.getNumberInstance();
        nf.setMaximumFractionDigits(0);
        yLabels.setNumberFormat(nf);
        yLabels.setAscending(false);
        
        // needs one color for "" in data
		int [] palette = new int[]{ColorLib.rgb(255, 0, 0), ColorLib.rgb(0, 0, 255), ColorLib.rgb(0, 255, 0), ColorLib.rgb(55, 155, 55)}; 
		ColorAction text2 = new ColorAction("xlab_axis",VisualItem.TEXTCOLOR,0); // no color
		ColorAction strokecol = new ColorAction("xlab_labels",VisualItem.STROKECOLOR,0); // no color
		DataColorAction datacolor = new DataColorAction("TABEL_LABELS","summary",Constants.NOMINAL, VisualItem.TEXTCOLOR, palette);
		
        Layout l = new LabelLayout("TABEL_LABELS");
        boundsLabelsX.getBounds().width = boundsLabelsX.getBounds().width - 50;
        l.setLayoutBounds(boundsLabelsX);
        
		ActionList draw = new ActionList();
		draw.add(xAxis);
		draw.add(yAxis);
		draw.add(xLabels);
		draw.add(xLabels2);
		draw.add(yLabels);
		draw.add(l);
		draw.add(text2);
		draw.add(strokecol);
		draw.add(datacolor);
		
		draw.add(new RepaintAction());
		vis.putAction("draw", draw);
		
		ActionList update = new ActionList();
		update.add(xAxis);
		update.add(yAxis);
		update.add(xLabels);
		update.add(xLabels2);
		update.add(yLabels);
		update.add(new LabelLayout("TABEL_LABELS"));
		update.add(text2);
		update.add(strokecol);
		update.add(new RepaintAction());
		vis.putAction("update", update);
		
		display.setHighQuality(true);
		display.setSize(700,450);
		display.setAutoscrolls(true);
		display.setBorder(BorderFactory.createTitledBorder("Calendar"));
		
		// data items will be displayed in front of the grid lines
		display.setItemSorter(new ItemSorter() {
			public int score(VisualItem item){
				int score = super.score(item);
				if(item.isInGroup("data")){
					score++;
				}
				return score;
			}
		});
		
		display.addComponentListener(new ComponentAdapter() {
			public void componentResized(ComponentEvent e) {
				updateBounds(display, boundsData, boundsLabelsX, boundsLabelsY);
				vis.run("update");
			}
		});
		
		vis.run("draw");
		
		return display;
	}
	
	private static void updateBounds(Display display, Rectangle2D boundsData,
			Rectangle2D boundsLabelsX, Rectangle2D boundsLabelsY) {
 
		int paddingLeft = 60;
		int paddingTop = 30;
		int paddingRight = 60;
		int paddingBottom = 30;
 
		int axisWidth = 20;
		int axisHeight = 10;
 
		Insets i = display.getInsets();
 
		int left = i.left + paddingLeft;
		int top = i.top + paddingTop;
		int innerWidth = display.getWidth() - i.left - i.right - paddingLeft
				- paddingRight;
		int innerHeight = display.getHeight() - i.top - i.bottom - paddingTop
				- paddingBottom;
 
		boundsData.setRect(left, top, innerWidth - axisWidth,
				innerHeight - axisHeight);
	
		boundsLabelsX.setRect(left, top,
				innerWidth - axisWidth, innerHeight);
		boundsLabelsY.setRect(left, top, innerWidth, innerHeight
				- axisHeight);
	}
	
	public void createAndShowGUI(JComponent display){
		JFrame frame = new JFrame();
		
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setTitle("T e s t L a y o u t");
		
		frame.getContentPane().add(display);
		
		frame.pack();
		frame.setVisible(true);
	}
}